package com.shangxia.lucky.lucky.job;

import com.shangxia.lucky.lucky.entity.Model;
import com.shangxia.lucky.lucky.job.write.CulomnWriterThread;
import com.shangxia.lucky.lucky.job.write.MatchWriterThread;
import com.shangxia.lucky.lucky.job.write.OverWriterThread;
import com.shangxia.lucky.lucky.writeHandler.MyTypeThreadWriteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import static com.shangxia.lucky.lucky.job.write.CulomnWriterThread.CULOMNWRITERTHREAD_LISTS;
import static com.shangxia.lucky.lucky.job.write.CulomnWriterThread.CulomnWriterThread_OVER_LOG;
import static java.util.stream.Collectors.toList;

/**
 * @ProjectName: monomer
 * @ClassName: MatchJob
 * @Time: 2021/9/2
 * @Author: zhouy
 * @Description:
 * @Experience:
 */

@Slf4j
@Component
public class MatchJob extends BaseJob {


    @Override
    public void job() throws IOException {
        OverWriterThread overWriterThread = new OverWriterThread(configText);

        //开始准备输出翻层结果
        new Thread(overWriterThread).start();

        //最后一行 初始化
        initLAST_LIST(configText.getBananaExportColumn());

        MatchWriterThread matchWriterThread = new MatchWriterThread(configText);
        CulomnWriterThread culomnWriterThread = new CulomnWriterThread(configText);

        new Thread(matchWriterThread).start();
        new Thread(culomnWriterThread).start();

        Map<String, Object> params = new HashMap<>();
        List<List<Integer>> lists = readCode(configText, configText.getBananaRealCodeFileName());
        params.put("matchLists", readCode(configText, configText.getBananaMatchFileName()));
        turnOver(params, lists, configText);

        matchWriterThread.stop();
        overWriterThread.stop();

        logOver();

    }

    @Override
    public void logOver() {
        while (true) {
            if ("matchJobWithOutRed".equals(configText.getBananaJobType()) && !CulomnWriterThread_OVER_LOG) {
                continue;
            }
            if (MatchWriterThread.WRITER_OVER_LOG && OverWriterThread.WRITER_OVER_LOG) {
                log.info("----------------------------------------------");
                log.info("-------------------程序运行完成-----------------");
                log.info("----------------------------------------------");
                break;
            }
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void exportLastRowResult()   {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < MatchJob.LAST_LIST.size(); i++) {
            list.add(0 == MatchJob.LAST_LIST.get(i) ? " " : "" + MatchJob.LAST_LIST.get(i));
        }
        MatchWriterThread.ageQueue.add(getBigList(list));
    }

    @Override
    public void initLAST_LIST(Integer column) {
        Integer[] arr = new Integer[7 * column];
        Arrays.fill(arr, 0);
        LAST_LIST = new ArrayList<>(Arrays.asList(arr));
    }


    @Override
    public void doPrivateJob(Map<String, Object> params, List<List<Integer>> realCodeLists) {
        List<List<Integer>> matchLists = (List<List<Integer>>) params.get("matchLists");
        List<Integer> columnList = (List<Integer>) params.get("columnList");
        Integer row = (Integer) params.get("row");
        Integer column = (Integer) params.get("column");
        for (int type = 0; type < matchLists.size(); type++) {
            Set<Integer> set = new HashSet<>(matchLists.get(type));
            set.addAll(columnList.subList(configText.getBananaCodeLength() - configText.getBananaSonCodeLength(), columnList.size()));
            //匹配个数
            int matchCount = configText.getBananaSonCodeLength() + matchLists.get(type).size() - set.size();
            Model model = new Model();
            model.setRow(row);
            model.setColumn(column);
            model.setType(type);
            model.setMatchCount(matchCount);
            if (row.equals(column)) {
                model.setAge(1);
                model.setMatchCountAll(matchCount);
            } else {
                Model lastModel = ROW_LAST_MODELS.get(column + "&" + type);
                if (lastModel.getPrized()) {
                    model.setAge(1);
                } else {
                    model.setAge(lastModel.getAge() + 1);
                }
                model.setMatchCountAll(lastModel.getMatchCountAll() + matchCount);
            }
            if (0 != model.getMatchCountAll()) {
                Double aveMatchCount = 1.0 * model.getMatchCountAll() / (1 + row - column);
                model.setAveMatchCount(String.format("%.2f", aveMatchCount));
            } else {
                model.setAveMatchCount("0");
            }
            model.setPrized(matchCount == Math.min(matchLists.get(type).size(), configText.getBananaSonCodeLength()));
            ROW_MODELS.put(column + "&" + type, model);
        }
    }

    /**
     * 计算最后一行数据
     *
     * @param resultList
     */
    @Override
    public void lastRowData(List<Model> resultList) {
        AtomicInteger stepAge = new AtomicInteger(3);
        AtomicInteger stepMax = new AtomicInteger(4);
        resultList.stream().forEach(model -> {
            Integer stepA = LAST_LIST.remove(stepAge.get());
            LAST_LIST.add(stepAge.get(), Math.max(stepA, model.getAge()));
            if (model.getPrized()) {
                Integer stepM = LAST_LIST.remove(stepMax.get());
                LAST_LIST.add(stepMax.get(), stepM + 1);
            }
            stepAge.addAndGet(7);
            stepMax.addAndGet(7);
        });
    }

    @Override
    public void exportRowResult(Map<String, Object> params) {
        List<Model> resultList = ROW_MODELS.values().stream().sorted(Comparator.comparingInt(Model::getType))
                .sorted(Comparator.comparingInt(Model::getColumn))
                .sorted(Comparator.comparingInt(Model::getAge).reversed())
                .limit(Math.min(ROW_MODELS.size(), configText.getBananaExportColumn())).collect(toList());

        lastRowData(resultList);

        List<String> ageList = new ArrayList<>();
        List<String> typeList = new ArrayList<>();
        ageList.add(1 + resultList.get(0).getRow() + "");
        typeList.add(1 + resultList.get(0).getRow() + "");
        AtomicInteger count = new AtomicInteger(0);
        AtomicInteger redIndex = new AtomicInteger(1);
        List<Integer> redList = new ArrayList<>();
        List<String> CULOMNWRITERTHREAD_LIST = new ArrayList<>();
        CULOMNWRITERTHREAD_LIST.add(ageList.get(0));
        resultList.stream().forEach(model -> {
            ageList.add("" + (1 + model.getColumn()));
            ageList.add("" + (1 + model.getType()));
            typeList.add("" + (1 + model.getType()));
            ageList.add("" + model.getAge());
            ageList.add("" + model.getMatchCount());
            CULOMNWRITERTHREAD_LIST.add("" + model.getMatchCount());
            ageList.add("" + model.getMatchCountAll());
            ageList.add("" + model.getAveMatchCount());
            ageList.add("" + model.getPrized());
            if (model.getPrized()) {
                count.getAndIncrement();
                redList.add(redIndex.get());
            }
            redIndex.getAndIncrement();
        });
        CULOMNWRITERTHREAD_LISTS.add(CULOMNWRITERTHREAD_LIST);
        MyTypeThreadWriteHandler.RED_LIST.add(redList);
        ageList.add(count.get() == 0 ? "" : "" + count.get());
        typeList.add(count.get() == 0 ? "" : "" + count.get());
        MatchWriterThread.ageQueue.add(getBigList(ageList));
        MatchWriterThread.typeQueue.add(getBigList(typeList));
    }

    public List<List<String>> getBigList(List<String> age) {
        List<List<String>> list = new ArrayList<>();
        list.add(age);
        return list;
    }

}
